/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package GUI;

import Domain.Player.*;
import Main.AppConstants;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.Serializable;
import javax.swing.*;
import javax.swing.border.TitledBorder;

/**
 *
 * @author sa11
 */
public class SetupGameDialog extends JDialog implements Serializable{

    // Players:
    private Player player1;
    private Player player2;
    // Components to validate data for:
    private Container content = getContentPane();
    //private JPanel
    private Box p1Panel;
    private Box p2Panel;
    private Box p1HPanel;
    private Box p2HPanel;
    private JPanel p1VPanel;
    private JPanel p2VPanel;
    private JPanel discP1;
    private JPanel discP2;
    private JPanel numberRounds;
    private JTextField textP1Name;
    private JTextField textP2Name;
    private JTextField textNumberOfRounds;
    private JRadioButton jcbTypeP1Human;
    private JRadioButton jcbTypeP1Computer;
    private JRadioButton jcbTypeP2Human;
    private JRadioButton jcbTypeP2Computer;
    private JRadioButton jcbDebugOn1;
    private JRadioButton jcbDebugOff1;
    private JRadioButton jcbDebugOn2;
    private JRadioButton jcbDebugOff2;
    private JLabel discImageP1;
    private JLabel discImageP2;
    private JSpinner jspnPly1;
    private JSpinner jspnPly2;
    // Component data:
    private Color player1Color = AppConstants.COLOR_DEFAULT_DISC_1;
    private Color player2Color = AppConstants.COLOR_DEFAULT_DISC_2;
    private String player1Name = "Player 1";
    private String player2Name = "Player 2";
    private String round;
    private int rounds;
    private PlayerType player1Type = PlayerType.HUMAN;
    private PlayerType player2Type = PlayerType.COMPUTER;

    public SetupGameDialog() {
        createDialog();
    }

    /**
     * Constructor used to fill the components with previous values
     */
    public SetupGameDialog(Player player1, Player player2) {
        if (player1 != null) {
            player1Name = player1.getName();
            player1Type = player1.getType();
            player1Color = player1.getDiscColor();
        }
        if (player2 != null) {
            player2Name = player2.getName();
            player2Type = player2.getType();
            player2Color = player2.getDiscColor();
        }
        createDialog();
    }

    /**
     * Create the dialog
     */
    public void createDialog() {
        setTitle(AppConstants.SETUP_GAME_DIALOG_TITLE);
        setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
        setModal(true);

        // Add components:
        content.add(createPlayerPanels());
        addNameFields();

        p1HPanel = Box.createHorizontalBox();
        p1Panel.add(p1HPanel);
        p2HPanel = Box.createHorizontalBox();
        p2Panel.add(p2HPanel);
        p1VPanel = new JPanel(new GridLayout(0, 1));
        p1HPanel.add(p1VPanel);
        p2VPanel = new JPanel(new GridLayout(0, 1));
        p2HPanel.add(p2VPanel);

        addTypeChooser();

        addDiscColor();
        addDebugChoser();
        addNumberOfRounds();

        content.add(createOKButton(), BorderLayout.SOUTH);

        pack();
        setLocationRelativeTo(null);
        setResizable(false);
        setVisible(true);
    }

    /**
     * Returns the Player object for the given playerNum
     */
    public Player getPlayer(int playerNum) {
        return playerNum % 2 == 0 ? player2 : player1;
    }

    /**
     * Separate the layout into two columns
     */
    private JPanel createPlayerPanels() {
        // Titled borders with font:
        Font headerFont = new Font(Font.DIALOG, Font.BOLD, 14);
        TitledBorder borderP1 = new TitledBorder("Player 1");
        borderP1.setTitleFont(headerFont);
        TitledBorder borderP2 = new TitledBorder("Player 2");
        borderP2.setTitleFont(headerFont);

        // Player columns:
        JPanel playerGrid = new JPanel(new GridLayout(0, 2));


        // Player #1:
        //p1Panel = new JPanel(new GridLayout(0, 1));
        p1Panel = Box.createVerticalBox();
        p1Panel.setBorder(borderP1);
        playerGrid.add(p1Panel);

        // Player #2:
        //p2Panel = new JPanel(new GridLayout(0, 1));
        p2Panel = Box.createVerticalBox();
        p2Panel.setBorder(borderP2);
        playerGrid.add(p2Panel);

        return playerGrid;
    }

    /**
     * Add player name componnents to the dialog
     */
    private void addNameFields() {
        TitledBorder border = new TitledBorder("Name");

        JPanel textP1Panel = new JPanel();
        textP1Panel.setBorder(border);
        textP1Name = new JTextField(player1Name, 25);
        textP1Panel.add(textP1Name);
        p1Panel.add(textP1Panel);

        JPanel textP2Panel = new JPanel();
        textP2Panel.setBorder(border);
        textP2Name = new JTextField(player2Name, 25);
        textP2Panel.add(textP2Name);
        p2Panel.add(textP2Panel);
    }

    /**
     * Add player type componnents to the dialog
     */
    private void addTypeChooser() {
        TitledBorder typeTitle = new TitledBorder("Type");

        // Player #1:
        Box typePanelP1 = Box.createVerticalBox();
        typePanelP1.setAlignmentY(BOTTOM_ALIGNMENT);
        typePanelP1.setBorder(typeTitle);
        jcbTypeP1Human = new JRadioButton("Human");
        jcbTypeP1Computer = new JRadioButton("Computer");
        // Pre-selected type:
        if (player1Type == PlayerType.HUMAN) {
            jcbTypeP1Human.setSelected(true);
        } else {
            jcbTypeP1Computer.setSelected(true);
        }

        // Group radio buttons:
        ButtonGroup groupTypeP1 = new ButtonGroup();
        groupTypeP1.add(jcbTypeP1Human);
        groupTypeP1.add(jcbTypeP1Computer);

        // Add radio buttons:
        typePanelP1.add(jcbTypeP1Human);
        typePanelP1.add(jcbTypeP1Computer);

        // Player #2:
        Box typePanelP2 = Box.createVerticalBox();
        typePanelP2.setAlignmentY(BOTTOM_ALIGNMENT);
        typePanelP2.setBorder(typeTitle);

        jcbTypeP2Human = new JRadioButton("Human");
        jcbTypeP2Computer = new JRadioButton("Computer");
        jcbTypeP2Computer.setSelected(true);

        // Pre-selected type:
        if (player2Type == PlayerType.HUMAN) {
            jcbTypeP2Human.setSelected(true);
        } else {
            jcbTypeP2Computer.setSelected(true);
        }

        // Group radio buttons:
        ButtonGroup groupTypeP2 = new ButtonGroup();
        groupTypeP2.add(jcbTypeP2Human);
        groupTypeP2.add(jcbTypeP2Computer);

        // Add radio buttons:
        typePanelP2.add(jcbTypeP2Human);
        typePanelP2.add(jcbTypeP2Computer);

        // Add type panels to the player panels:
        p1VPanel.add(typePanelP1);
        p2VPanel.add(typePanelP2);
    }

    /**
     * Add player type componnents to the dialog
     */
    private void addDebugChoser() {
        TitledBorder typeTitle = new TitledBorder("Debug");

        // Player #1:
        JPanel debugPanelP1 = new JPanel();
        debugPanelP1.setAlignmentY(BOTTOM_ALIGNMENT);
        debugPanelP1.setBorder(typeTitle);
        jcbDebugOn1 = new JRadioButton("On");
        jcbDebugOff1 = new JRadioButton("Off");
        // Pre-selected type:
        jcbDebugOff1.setSelected(true);

        // Group radio buttons:
        ButtonGroup groupDebugP1 = new ButtonGroup();
        groupDebugP1.add(jcbDebugOn1);
        groupDebugP1.add(jcbDebugOff1);

        // Add radio buttons:
        debugPanelP1.add(jcbDebugOn1);
        debugPanelP1.add(jcbDebugOff1);

        // Player #2:
        JPanel debugPanelP2 = new JPanel();
        debugPanelP2.setAlignmentY(BOTTOM_ALIGNMENT);
        debugPanelP2.setBorder(typeTitle);

        jcbDebugOn2 = new JRadioButton("On");
        jcbDebugOff2 = new JRadioButton("Off");
        jcbDebugOff2.setSelected(true);

        // Pre-selected type:
        jcbDebugOff2.setSelected(true);

        // Group radio buttons:
        ButtonGroup groupDebugP2 = new ButtonGroup();
        groupDebugP2.add(jcbDebugOn2);
        groupDebugP2.add(jcbDebugOff2);

        // Add radio buttons:
        debugPanelP2.add(jcbDebugOn2);
        debugPanelP2.add(jcbDebugOff2);

        // Add type panels to the player panels:
        p1Panel.add(debugPanelP1);
        p2Panel.add(debugPanelP2);
    }

    /**
     * Add disc colors
     */
    private void addDiscColor() {
        TitledBorder titleDisc = new TitledBorder("Disc Color");

        // Player #1:
        discP1 = new JPanel();
        discP1.setBorder(titleDisc);
        p1HPanel.add(discP1);

        // Player #2:
        discP2 = new JPanel();
        discP2.setBorder(titleDisc);
        p2HPanel.add(discP2);

        createDiscIcons();
    }

    /**
     * Update the disc icons
     */
    private void updateDiscIcons() {
        discImageP1.setIcon(new DiscIcon(player1Color));
        discImageP2.setIcon(new DiscIcon(player2Color));
    }

    /**
     * Add the disc icons
     */
    private void createDiscIcons() {
        // Player #1:
        discImageP1 = new JLabel();
        discImageP1.setIcon(new DiscIcon(player1Color));
        discImageP1.addMouseListener(new ColorListener(1));
        discP1.add(discImageP1);

        // Player #2:
        discImageP2 = new JLabel();
        discImageP2.setIcon(new DiscIcon(player2Color));
        discImageP2.addMouseListener(new ColorListener(2));
        discP2.add(discImageP2);
    }

    /**
     * Add the OK button component to the dialog
     */
    private JPanel createOKButton() {
        JPanel buttonPanel = new JPanel(new FlowLayout());
        buttonPanel.setBackground(AppConstants.COLOR_PANEL_BACKGROUND);
        buttonPanel.setBorder(BorderFactory.createMatteBorder(1, 0, 0, 0, AppConstants.COLOR_PANEL_BORDER));

        // OK button:
        JButton jBtnOK = new JButton("OK");
        jBtnOK.setBackground(AppConstants.COLOR_PANEL_BACKGROUND);
        jBtnOK.addActionListener(new ActionListener() {

            /**
             * Button listener: OK If there's valid data = create players
             * otherwise show error dialog
             */
            @Override
            public void actionPerformed(ActionEvent e) {
                if (isValidInput()) {
                    createPlayers();
                    dispose();
                } else {
                    //new ErrorDialog("Enter correct values!");
                }
            }
        });
        buttonPanel.add(jBtnOK);

        return buttonPanel;
    }

    /**
     * Check whether or not the input is valid
     */
    public boolean isValidInput() {
        return isValidNames() && isValidTypes() && isValidNumberOfRounds();
    }

    /**
     * Validate names
     */
    public boolean isValidNames() {
        player1Name = textP1Name.getText().trim();
        player2Name = textP2Name.getText().trim();

        return (!player1Name.equals("") && !player2Name.equals(""));
    }

    /**
     * Validate types
     */
    public boolean isValidTypes() {
        player1Type = (jcbTypeP1Human.isSelected() ? PlayerType.HUMAN
                : (jcbTypeP1Computer.isSelected() ? PlayerType.COMPUTER
                : null));
        player2Type = (jcbTypeP2Human.isSelected() ? PlayerType.HUMAN
                : (jcbTypeP2Computer.isSelected() ? PlayerType.COMPUTER
                : null));

        return (player1Type != null && player2Type != null);
    }

    /**
     * Create players
     */
    public void createPlayers() {
        boolean debug;
        player1 = player1Type == PlayerType.HUMAN
                ? new Human(player1Name, Disc.ONE, player1Color)
                : new Computer(player1Name, Disc.ONE, player1Color);
        player2 = player2Type == PlayerType.HUMAN
                ? new Human(player2Name, Disc.TWO, player2Color)
                : new Computer(player2Name, Disc.TWO, player2Color);
        /*
         * if (player1.getType() == PlayerType.COMPUTER) { ((Computer)
         * player1).setPly((Integer) jspnPly1.getValue()); ((Computer)
         * player1).setDebug(jcbDebugOn1.isSelected()); }
         *
         * if (player2.getType() == PlayerType.COMPUTER) { ((Computer)
         * player2).setPly((Integer) jspnPly2.getValue()); ((Computer)
         * player2).setDebug(jcbDebugOn2.isSelected()); }
         *
         */
    }

    private void addNumberOfRounds() {
        TitledBorder typeTitle = new TitledBorder("Number Of Rounds");

        // Player #1:
        JPanel roundPanel = new JPanel();
        roundPanel.setAlignmentY(BOTTOM_ALIGNMENT);
        roundPanel.setBorder(typeTitle);
        textNumberOfRounds = new JTextField("1");
        textNumberOfRounds.setColumns(14);
        roundPanel.add(textNumberOfRounds);


        // Add type panels to the player panels:
        p1Panel.add(roundPanel);
    }

    private boolean isValidNumberOfRounds() {
        round = textNumberOfRounds.getText().trim();
        try {
            AppConstants.numberOfRounds = Integer.parseInt(round);
            return true;
        } catch (Exception ex) {
            System.out.println("FUCKING FEL PÅ TALET");
            return false;
        }
    }

    /**
     * Color listener
     */
    private class ColorListener implements MouseListener {

        private int playerNum;

        public ColorListener(int playerNum) {
            this.playerNum = playerNum;
        }

        @Override
        public void mouseClicked(MouseEvent e) {
            JColorChooser colorChooser = new JColorChooser();
            Color selectedColor = colorChooser.showDialog(content,
                    "Choose disc color",
                    (playerNum % 2 == 0 ? player2Color : player1Color));

            if (selectedColor == null) {
                return;
            }

            if (playerNum % 2 == 0) {
                player2Color = selectedColor;
            } else {
                player1Color = selectedColor;
            }
            // Update the disc icons with the new color:
            updateDiscIcons();
        }

        @Override
        public void mousePressed(MouseEvent e) {
        }

        @Override
        public void mouseReleased(MouseEvent e) {
        }

        @Override
        public void mouseEntered(MouseEvent e) {
        }

        @Override
        public void mouseExited(MouseEvent e) {
        }
    }


    /**
     * Creates a JPanel with a spinner for changing how many moves ahead the
     * computer will look
     */
}
